package com.zhifei.system.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhifei.common.utils.Constant;
import com.zhifei.common.utils.DateUtils;
import com.zhifei.common.utils.Result;
import com.zhifei.common.utils.StringUtils;
import com.zhifei.common.utils.excel.ExcelUtils;
import com.zhifei.system.domain.EmployeeMonthEntity;
import com.zhifei.system.domain.dto.EmployeeMonthExcelDTO;
import com.zhifei.system.domain.dto.UpdateEmployeeMonthDTO;
import com.zhifei.system.domain.vo.EmployeeMonthExcelVo;
import com.zhifei.system.domain.vo.EmployeeMonthSummaryVo;
import com.zhifei.system.domain.vo.EmployeeMonthVo;
import com.zhifei.system.mapper.EmployeeMonthMapper;
import com.zhifei.system.service.EmployeeMonthService;
import com.zhifei.system.util.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class EmployeeMonthServiceImpl extends ServiceImpl<EmployeeMonthMapper, EmployeeMonthEntity> implements EmployeeMonthService {

    @Autowired
    private EmployeeMonthMapper employeeMonthMapper;

    @Override
    public PageUtils pageMonth(Map<String, Object> params) {
        Page page = new Page(Long.parseLong((String)params.get(Constant.PAGE)),Long.parseLong((String)params.get(Constant.LIMIT)));
        String jobNum = (String) params.get("jobNum");
        String fullName = (String) params.get("fullName");
        String customerName = (String) params.get("customerName");
        String projectName = (String) params.get("projectName");
        String serviceManager = (String) params.get("serviceManager");
        String recruitHr = (String) params.get("recruitHr");
        String monthStartDate = (String) params.get("monthStartDate");
        String monthEndDate = (String) params.get("monthEndDate");
        String collectionStartDate = (String) params.get("collectionStartDate");
        String collectionEndDate = (String) params.get("collectionEndDate");
        List<EmployeeMonthVo> employeeList = employeeMonthMapper.pageMonth(page,jobNum,fullName,customerName,projectName,serviceManager,recruitHr,monthStartDate,monthEndDate,collectionStartDate,collectionEndDate);
        page.setRecords(employeeList);
        return new PageUtils(page);
    }

    @Override
    public List<EmployeeMonthExcelVo> listMonth(Map<String, Object> params) {
        String jobNum = (String) params.get("jobNum");
        String fullName = (String) params.get("fullName");
        String customerName = (String) params.get("customerName");
        String projectName = (String) params.get("projectName");
        String serviceManager = (String) params.get("serviceManager");
        String recruitHr = (String) params.get("recruitHr");
        String monthStartDate = (String) params.get("monthStartDate");
        String monthEndDate = (String) params.get("monthEndDate");
        String collectionStartDate = (String) params.get("collectionStartDate");
        String collectionEndDate = (String) params.get("collectionEndDate");
        return employeeMonthMapper.listMonth(jobNum,fullName,customerName,projectName,serviceManager,recruitHr,monthStartDate,monthEndDate,collectionStartDate,collectionEndDate);
    }

    @Override
    public Result importMonth(MultipartFile multipartFile) {
        List<EmployeeMonthEntity> employeeMonthEntityList = new ArrayList<>();
        List<Object> employeeMonthExcelList = ExcelUtils.importExcel(multipartFile, new EmployeeMonthExcelDTO());
        if (Objects.isNull(employeeMonthExcelList)) {
            return Result.error("文件格式不支持，请采用样式模板");
        }
        for (int i = 0; i < employeeMonthExcelList.size(); i++) {
            EmployeeMonthExcelDTO employeeMonthExcelDTO = (EmployeeMonthExcelDTO) employeeMonthExcelList.get(i);
            if (StringUtils.isEmpty(employeeMonthExcelDTO.getId())) {
                return Result.error("第" + (i + 1) + "行数据中：" + "id不能为空！");
            }
            if (StringUtils.isEmpty(employeeMonthExcelDTO.getSettlementAmount())) {
                return Result.error("第" + (i + 1) + "行数据中：" + "结算金额不能为空！");
            }
            if (StringUtils.isEmpty(employeeMonthExcelDTO.getCollectionAmount())) {
                return Result.error("第" + (i + 1) + "行数据中：" + "回款金额不能为空！");
            }
            if (StringUtils.isEmpty(employeeMonthExcelDTO.getCollectionDate())) {
                return Result.error("第" + (i + 1) + "行数据中：" + "回款日期不能为空！");
            }
            Date collectionDate = DateUtils.parseDate(employeeMonthExcelDTO.getCollectionDate());
            if(collectionDate==null){
                return Result.error("第" + (i + 1) + "行数据中：" + "回款日期格式不正确！");
            }
            EmployeeMonthEntity employeeMonthEntity = employeeMonthMapper.selectById(employeeMonthExcelDTO.getId());
            if(employeeMonthEntity==null){
                return Result.error("第" + (i + 1) + "行数据中：" + "id值不存在！");
            }
            employeeMonthEntity.setSettlementAmount(new BigDecimal(employeeMonthExcelDTO.getSettlementAmount()));
            employeeMonthEntity.setCollectionAmount(new BigDecimal(employeeMonthExcelDTO.getCollectionAmount()));
            employeeMonthEntity.setCollectionDate(collectionDate);
            employeeMonthEntityList.add(employeeMonthEntity);
            this.caclPriceBySettlementAmount(employeeMonthEntity,new BigDecimal(employeeMonthExcelDTO.getSettlementAmount()));
        }
        this.updateBatchById(employeeMonthEntityList);
        return Result.success("导入成功");
    }

    @Override
    public EmployeeMonthSummaryVo getMonthSummary(Map<String, Object> params) {
        String jobNum = (String) params.get("jobNum");
        String fullName = (String) params.get("fullName");
        String customerName = (String) params.get("customerName");
        String projectName = (String) params.get("projectName");
        String serviceManager = (String) params.get("serviceManager");
        String recruitHr = (String) params.get("recruitHr");
        String monthStartDate = (String) params.get("monthStartDate");
        String monthEndDate = (String) params.get("monthEndDate");
        String collectionStartDate = (String) params.get("collectionStartDate");
        String collectionEndDate = (String) params.get("collectionEndDate");
        EmployeeMonthSummaryVo vo = employeeMonthMapper.getMonthSummary(jobNum,fullName,customerName,projectName,serviceManager,recruitHr,monthStartDate,monthEndDate,collectionStartDate,collectionEndDate);
        return vo;
    }

    @Override
    public Result updateMonth(UpdateEmployeeMonthDTO dto) {
        EmployeeMonthEntity entity = employeeMonthMapper.selectById(dto.getId());
        if(StringUtils.isNotEmpty(dto.getSettlementAmount())){
            entity.setSettlementAmount(new BigDecimal(dto.getSettlementAmount()));
        }
        if(StringUtils.isNotEmpty(dto.getCollectionAmount())){
            entity.setCollectionAmount(new BigDecimal(dto.getCollectionAmount()));
        }
        if(StringUtils.isNotEmpty(dto.getCollectionDate())){
            try {
                entity.setCollectionDate(new SimpleDateFormat("yyyy-MM-dd").parse(dto.getCollectionDate()));
            } catch (ParseException e) {
            }
        }
        baseMapper.updateById(entity);
        if(StringUtils.isNotEmpty(dto.getSettlementAmount())){
            this.caclPriceBySettlementAmount(entity,new BigDecimal(dto.getSettlementAmount()));
        }
        return Result.success(entity);
    }

    /**
     * 根据结算金额重新计算
     */
    @Override
    public void caclPriceBySettlementAmount(EmployeeMonthEntity employeeMonthEntity,BigDecimal settlementAmount){
        BigDecimal taxRate = employeeMonthEntity.getTaxRate();
        BigDecimal CompanyLaborCost = employeeMonthEntity.getCompanyLaborCost();
        BigDecimal taxAmount = settlementAmount.multiply((taxRate.divide(new BigDecimal(100),2, RoundingMode.HALF_UP)));//税额（报价月薪*税率）
        employeeMonthEntity.setTaxAmount(taxAmount);
        BigDecimal grossProfit = settlementAmount.subtract(CompanyLaborCost).subtract(taxAmount);//毛利（报价-薪资-社保公积金-税额）
        employeeMonthEntity.setGrossProfit(grossProfit);
        BigDecimal grossProfitRate = grossProfit.divide(settlementAmount,2,RoundingMode.HALF_UP);//毛利率（毛利/报价，如有调整实时更新，低于18%显示红色预警）
        employeeMonthEntity.setGrossProfitRate(grossProfitRate);
        BigDecimal companyManagementCost = settlementAmount.multiply(new BigDecimal(0.1));//公司管理成本（报价*10%）
        employeeMonthEntity.setCompanyManagementCost(companyManagementCost);
        BigDecimal riskReserve = settlementAmount.multiply(new BigDecimal(0.05));//风险储备金（报价*5%）
        employeeMonthEntity.setRiskReserve(riskReserve);
        BigDecimal travelExpenses = BigDecimal.ZERO;//差旅费用（初始值为0，后续接口取金蝶中人员差旅成本）
        employeeMonthEntity.setTravelExpenses(travelExpenses);
        BigDecimal marketingSubsidies = settlementAmount.multiply(new BigDecimal(0.01));//市场营销补贴（报价*1%）
        employeeMonthEntity.setMarketingSubsidies(marketingSubsidies);
        BigDecimal financialExpenses = settlementAmount.multiply(new BigDecimal(0.012));//财务费用（报价*1.2%）
        employeeMonthEntity.setFinancialExpenses(financialExpenses);
        String paymentMethod = employeeMonthEntity.getPaymentMethod();
        String businessSource = employeeMonthEntity.getBusinessSource();
        String userRank = employeeMonthEntity.getUserRank();
        BigDecimal salesCommission = BigDecimal.ZERO;//销售提成（毛利率<=18%为0，毛利率在18到30%为毛利*2%，毛利率在30%以上为毛利*2.5%）
        BigDecimal commissionRate = BigDecimal.ZERO;//提成比例
        if(grossProfitRate.compareTo(new BigDecimal(0.1))<=0){
            commissionRate = BigDecimal.ZERO;
        }else if(grossProfitRate.compareTo(new BigDecimal(0.1))>0 && grossProfitRate.compareTo(new BigDecimal(0.2))<=0){
            commissionRate = new BigDecimal(0.01);
        }else if(grossProfitRate.compareTo(new BigDecimal(0.2))>0 && grossProfitRate.compareTo(new BigDecimal(0.3))<=0){
            commissionRate = new BigDecimal(0.03);
        }else if(grossProfitRate.compareTo(new BigDecimal(0.3))>0){
            commissionRate = new BigDecimal(0.05);
        }
        //鼓励月结回款，月结项目再加0.5%，独立新拓项目增加1%。
        if(grossProfitRate.compareTo(new BigDecimal(0.1))>0){
            if(StringUtils.isNotEmpty(paymentMethod) && paymentMethod.equals("月结")){
                commissionRate = commissionRate.add(new BigDecimal(0.005));
            }
            if(StringUtils.isNotEmpty(businessSource) && businessSource.equals("个人开拓")){
                commissionRate = commissionRate.add(new BigDecimal(0.01));
            }
        }
        salesCommission = grossProfit.multiply(commissionRate);
        BigDecimal recruitCommission = BigDecimal.ZERO;//招聘提成（按照初级250元/人、中级350元/人、高级岗位450元/人；毛利在30%以上增加100元/人）
        if(StringUtils.isNotEmpty(userRank)){
            if(userRank.equals("初级")){
                recruitCommission = new BigDecimal(250);
            }else if(userRank.equals("初中级") || userRank.equals("中级")){
                recruitCommission = new BigDecimal(350);
            }else if(userRank.equals("中高级") || userRank.equals("高级")){
                recruitCommission = new BigDecimal(450);
            }
        }
        if(grossProfitRate.compareTo(new BigDecimal(0.3))>0){
            recruitCommission = recruitCommission.add(new BigDecimal(100));
        }
        employeeMonthEntity.setSalesCommission(salesCommission);//销售提成（毛利率<=18%为0，毛利率在18到30%为毛利*2%，毛利率在30%以上为毛利*2.5%）
        employeeMonthEntity.setRecruitCommission(recruitCommission);
        employeeMonthEntity.setPaymentMethod(paymentMethod);
        employeeMonthEntity.setBusinessSource(businessSource);
//        BigDecimal talentServiceCommission = grossProfit.multiply(new BigDecimal(0.02));//人才服务部提成（毛利*2%）
        BigDecimal talentServiceCommission = BigDecimal.ZERO;
        employeeMonthEntity.setTalentServiceCommission(talentServiceCommission);
        BigDecimal netProfit = grossProfit.subtract(companyManagementCost).subtract(riskReserve).subtract(travelExpenses)
                .subtract(marketingSubsidies).subtract(financialExpenses).subtract(salesCommission).subtract(talentServiceCommission).subtract(recruitCommission);//纯利（毛利-公司管理成本-风险储备金-差旅费用-市场营销补贴-财务费用-销售提成-人才服务部提成）
        employeeMonthEntity.setNetProfit(netProfit);
        BigDecimal netProfitRate = netProfit.divide(settlementAmount,2,RoundingMode.HALF_UP);//纯利率（纯利/报价）
        employeeMonthEntity.setNetProfitRate(netProfitRate);
        baseMapper.updateById(employeeMonthEntity);
    }

    /**
     * 根据差旅费用重新计算
     */
    @Override
    public void caclPriceByTravelExpenses(String jobNum,String employeeMonth,BigDecimal travelExpenses){
        EmployeeMonthEntity employeeMonthEntity = employeeMonthMapper.getByJobNumAndMonth(jobNum,employeeMonth);
        if(employeeMonthEntity==null){
            return;
        }
        employeeMonthEntity.setTravelExpenses(travelExpenses);
        BigDecimal companyManagementCost = employeeMonthEntity.getCompanyManagementCost();
        BigDecimal riskReserve = employeeMonthEntity.getRiskReserve();
        BigDecimal marketingSubsidies = employeeMonthEntity.getMarketingSubsidies();
        BigDecimal financialExpenses = employeeMonthEntity.getFinancialExpenses();
        BigDecimal grossProfit = employeeMonthEntity.getGrossProfit();
        BigDecimal salesCommission = employeeMonthEntity.getSalesCommission();
        BigDecimal talentServiceCommission = employeeMonthEntity.getTalentServiceCommission();
        employeeMonthEntity.setTalentServiceCommission(talentServiceCommission);
        BigDecimal netProfit = grossProfit.subtract(companyManagementCost).subtract(riskReserve).subtract(travelExpenses)
                .subtract(marketingSubsidies).subtract(financialExpenses).subtract(salesCommission).subtract(talentServiceCommission);//纯利（毛利-公司管理成本-风险储备金-差旅费用-市场营销补贴-财务费用-销售提成-人才服务部提成）
        employeeMonthEntity.setNetProfit(netProfit);
        BigDecimal settlementAmount = employeeMonthEntity.getSettlementAmount();
        if(settlementAmount==null || settlementAmount.compareTo(BigDecimal.ZERO)==0){
            settlementAmount = employeeMonthEntity.getQuoteMonthPay();
        }
        BigDecimal netProfitRate = netProfit.divide(settlementAmount,2,RoundingMode.HALF_UP);//纯利率（纯利/报价）
        employeeMonthEntity.setNetProfitRate(netProfitRate);
        baseMapper.updateById(employeeMonthEntity);
    }

    @Override
    public EmployeeMonthEntity getByJobNumAndMonth(String jobNum, String employeeMonth) {
        return employeeMonthMapper.getByJobNumAndMonth(jobNum,employeeMonth);
    }

}
